//可变参数宏 __VA_ARGS__
//当可变参数...没有表示参数时，后面的##可以去掉逗号
#ifndef __MYLOG_HPP__
#define __MYLOG_HPP__

#include <log4cpp/Category.hh>

#include <sstream>

using std::string;
namespace du {

class Mylog {
public:
    static Mylog *getInstance() {
        if(_pInstance == nullptr) {
            _pInstance = new Mylog();
        }
        return _pInstance;
    }
    static void destroy() {
        if(nullptr != _pInstance) {
            delete _pInstance;
            _pInstance = nullptr;
        }
    }

    template <class ...Args>
        void error(const char *msg, Args ...args) {
            _mycat.error(msg, args...);
        }
    template <class ...Args>
        void warn(const char *msg, Args ...args) {
            _mycat.warn(msg, args...);
        }
    template <class ...Args>
        void debug(const char *msg, Args ...args) {
            _mycat.debug(msg, args...);
        }
    template <class ...Args>
        void info(const char *msg, Args ...args) {
            _mycat.info(msg, args...);
        }

private:
    Mylog();//构造函数的实现放在实现文件
    ~Mylog();
    Mylog(const Mylog &rhs) = delete;
    Mylog &operator=(const Mylog &rhs) = delete;

private:
    static Mylog *_pInstance;
    log4cpp::Category &_mycat;//引用数据成员要放到初始化列表初始化
};

//多个文件引用了myLog.hpp的话会出现多次定义的情况，因此设置为inline函数
inline
string int2str(int num) {
    std::ostringstream oss;
    oss << num;
    return oss.str();
}

#define addprefix(msg)  string ("[").append(__FILE__)   \
            .append(":").append(__FUNCTION__)           \
            .append(":").append(int2str(__LINE__))      \
            .append("] ").append(msg).c_str()

#define LogError(msg, ...) Mylog::getInstance()->error(addprefix(msg), ##__VA_ARGS__)
#define LogWarn(msg, ...) Mylog::getInstance()->warn(addprefix(msg), ##__VA_ARGS__)
#define LogInfo(msg, ...) Mylog::getInstance()->info(addprefix(msg), ##__VA_ARGS__)
#define LogDebug(msg, ...) Mylog::getInstance()->debug(addprefix(msg), ##__VA_ARGS__)

} //end of namespace du


#endif

